package com.kly.sc.api.application.controller.im;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.json.JSONUtil;
import com.fqgj.common.api.Response;
import com.fqgj.common.utils.CollectionUtils;
import com.google.common.collect.Lists;
import com.kly.sc.api.application.controller.config.response.SelectVal;
import com.kly.sc.api.application.controller.im.request.OpenChatReq;
import com.kly.sc.api.application.controller.im.response.ChatterResponse;
import com.kly.sc.api.application.controller.im.response.TurnOns;
import com.kly.sc.api.application.helper.RequestLocalInfo;
import com.kly.sc.api.application.service.user.HasMemberBenefitsValidationService;
import com.kly.sc.api.application.service.utils.BaseComponent;
import com.kly.sc.api.infras.utils.StringUtils;
import com.kly.user.chatterService.ChatService;
import com.kly.user.dto.*;
import com.kly.user.dto.chatter.request.ConversationReq;
import com.kly.user.enums.AppEnum;
import com.kly.user.enums.ConversationType;
import com.kly.user.service.UserMsgService;
import com.kly.user.service.UserService;
import com.kly.user.service.WhiteListService;
import com.kly.user.service.WlmService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@RestController
@RequestMapping("/api/chat")
public class ChatController extends BaseComponent {

    @Resource
    ChatService chatService;
    @Resource
    UserMsgService userMsgService;
    @Resource
    BaseComponent baseComponent;
    @Resource
    HasMemberBenefitsValidationService hasMemberBenefitsValidationService;
    @Resource
    UserService userService;
    @Resource
    WlmService wlmService;
    @Resource
    private WhiteListService whiteListService;

//    @NacosValue(value = "${customer.service.userCode}")
//    private String customerServiceUserCode;
//    @NacosValue(value = "${unlimit.chat.message.num:99999}")
//    private Integer unLimitChatMessageNum;
//    @NacosValue(value = "${user.flashchat.default.msg:You summoned a Flash Chat.}")
//    private String userSendFlashChatMsg;
//    @NacosValue(value = "${model.flashchat.default.msg:You got hit with a Flash Chat.}")
//    private String modelSendFlashChatMsg;
//    @NacosValue(value = "${default.msg:Start Chatting}")
//    private String defaultChatMsg;
    /**
     * 进入会话
     */
    private static final Integer enterChat = 1;

    @RequestMapping("/openchat")
//    @UserBenefitControl(benefit = "conversations")
    public Response openChatter(@RequestBody OpenChatReq req) {
        final String userCode = RequestLocalInfo.getCurrentUser().getUserCode();
        final String appCode = RequestLocalInfo.getRequestBasicInfo().getAppCode();

        // 客服管理
        String customerServiceUserCode = getCustomerServiceUserCode(appCode);

        if (customerServiceUserCode.equals(req.getUserCodeFriend()) || customerServiceUserCode.equals(userCode)) {
            ChatterResponse response = new ChatterResponse();
            response.setMessagesNumber(getCustomerChatLimitNum(appCode));
            return Response.ok(response);
        }

        boolean turnOns = CollUtil.isNotEmpty(RequestLocalInfo.getCurrentUser().getTurnOnsList());
        final ConversationReq conversationReq = ConversationReq.builder().fromUserCode(userCode).toUserCode(req.getUserCodeFriend())
                .type(req.getType()).source(AppEnum.MEBOO.getAppCode()).latestTime(new Date()).conversationType(1).build();

        ChatterResponse chatterResponse = new ChatterResponse();
        chatterResponse.setTurnOns(turnOns);

        //进入会话
        if (req.getType().equals(enterChat)) {
            // 是否为会员
            boolean isMember = baseComponent.retrieveMemberFromCacheOrService(userCode) != null;
            chatterResponse.setMember(isMember);

            if (isMember) {
                chatterResponse.setMessagesNumber(getCustomerChatLimitNum(appCode));
            } else {
                final Integer remainSendMessageNum = hasMemberBenefitsValidationService
                        .getRemainSendMessageNum(conversationReq.getFromUserCode(), conversationReq.getToUserCode());
                chatterResponse.setMessagesNumber(remainSendMessageNum);
            }

            // 设置在线状态
            Response<UserBaseDto> modelResp = setOnlineStatus(req, chatterResponse);
            // 设置turnOns信息
            final List<UserTurnOnsDto> userTurnOnsDtos = userService.getuserTurnOnsList();
            final Response<UserBaseDto> userResp = userService.getUserBaseInfo(userCode);

            Response<List<String>> whiteList = whiteListService.userCodeList();
            boolean inWhiteList = CollectionUtils.isNotEmpty(whiteList.getData()) && whiteList.getData().contains(userCode);
            // 【meboo-v3.1.3】加白账号，不显示顶部的卡片
            if (!inWhiteList) {
                setTurns(userResp, modelResp, chatterResponse, userTurnOnsDtos);
            } else {
                chatterResponse.setTurnOnsNum(0);
                chatterResponse.setTurnOnsList(Lists.newArrayList());
            }

            // 设置flashChat
            setFlashChat(userCode, req.getUserCodeFriend(), chatterResponse);

            //todo 合并
            chatService.storageConversation(conversationReq);
            chatService.updateUserLeaveTime(conversationReq);

            chatterResponse.setMatchFlag(0);
            Response<Integer> response = wlmService.getUserMatch(userCode, req.getUserCodeFriend());
            if (response.isSuccess()) {
                chatterResponse.setMatchFlag(response.getData() == null ? 0 : response.getData());
            }

//            Response<UserGpsDto> userGpsDtoResponse = userService.getGpsInfo(req.getUserCodeFriend());
//            if (response.isSuccess() && userGpsDtoResponse.getData() != null) {
//                chatterResponse.setCity(userGpsDtoResponse.getData().getCity());
//                chatterResponse.setState(userGpsDtoResponse.getData().getState());
//            }

            // 【meboo-v3.1.3】加白账号，不显示顶部的卡片
            if (!inWhiteList) {
                final Response<UserTagDto> userTagInfoResponse = userService.getUserTagInfo(req.getUserCodeFriend());
                if (userTagInfoResponse.isSuccess() && userTagInfoResponse.getData() != null) {
                    final UserTagDto userTag = userTagInfoResponse.getData();
                    if (userTag.getUserWant() != null) {
                        final com.kly.user.dto.SelectVal iWantList = userTag.getUserWant();
                        chatterResponse.setUserWant(SelectVal.builder().code(iWantList.getCode()).value(iWantList.getValue()).build());
                    }
                    if (super.showPPPV()) {
                        chatterResponse.setYouAccept(null);
                    } else {
                        if (userTag.getYouAccept() != null) {
                            final List<com.kly.user.dto.SelectVal> youAcceptList = userTag.getYouAccept();
                            if (CollectionUtils.isNotEmpty(youAcceptList)) {
                                final List<SelectVal> youAccept = youAcceptList.stream().map(o -> SelectVal.builder().code(o.getCode()).value(o.getValue()).build()).collect(Collectors.toList());
                                chatterResponse.setYouAccept(youAccept);
                            }
                        }
                    }
                }
            }

            Integer userMessageNum = userMsgService.selectMessageCount(userCode);
            chatterResponse.setUserMessageNum(userMessageNum);
            List<Integer> popImNums = userMsgService.getPopImNums(appCode);
            chatterResponse.setImReadyCountList(popImNums);
            List<Integer> imTipsCountList = new ArrayList<>();
            imTipsCountList.add(5);
            imTipsCountList.add(30);
            imTipsCountList.add(50);
            chatterResponse.setImTipsCountList(imTipsCountList);
            return Response.ok(chatterResponse);
        }
        // 离开会话
        else {
            // 未读消息更新为已读
            chatService.readMsg(req.getUserCodeFriend(), userCode, null);

            chatterResponse.setMatchFlag(0);
            chatterResponse.setEffectiveChat(getSumUserMsgDtos(userCode, req) > 0);
            chatService.updateUserLeaveTime(conversationReq);
            return Response.ok(chatterResponse);
        }
    }

    private void setFlashChat(String userCode, String modelUserCode, ChatterResponse chatterResponse) {
        final String appCode = RequestLocalInfo.getRequestBasicInfo().getAppCode();

        final Response<List<WlmUserDto>> userRelationResp = wlmService.getUserRelation(userCode, modelUserCode);
        if (Objects.nonNull(userRelationResp) && userRelationResp.isSuccess() && CollectionUtils.isNotEmpty(userRelationResp.getData())) {
            final WlmUserDto user = userRelationResp.getData().get(0);
            if (user != null && user.getFlashchatFlag() != null && user.getFlashchatFlag()) {
                chatterResponse.setFlashChatMsg(getUserFlashChatMsg(appCode));
                chatterResponse.setFlashchatFlag(1);
                return;
            }
        }
        final Response<List<WlmUserDto>> modelRelationResp = wlmService.getUserRelation(modelUserCode, userCode);
        if (Objects.nonNull(modelRelationResp) && modelRelationResp.isSuccess() && CollectionUtils.isNotEmpty(modelRelationResp.getData())) {
            final WlmUserDto model = modelRelationResp.getData().get(0);
            if (model != null && model.getFlashchatFlag() != null && model.getFlashchatFlag()) {
                chatterResponse.setFlashChatMsg(getModelSendFlashChatMsg(appCode));
                chatterResponse.setFlashchatFlag(1);
                return;
            }
        }

        chatterResponse.setFlashChatMsg(getDefaultChatMsg(appCode));
        chatterResponse.setFlashchatFlag(0);
    }

    /**
     * 显示的是用户与model的turnOns交集
     */
    private void setTurns(Response<UserBaseDto> userBaseResp, Response<UserBaseDto> modelResp, ChatterResponse chatterResponse, List<UserTurnOnsDto> userTurnOnsDtos) {
        if (super.showTurnOns()) {
            chatterResponse.setTurnOnsNum(0);
            chatterResponse.setTurnOnsList(Lists.newArrayList());
            return;
        }
        final List<Integer> userTurnOns = getTurnOns(userBaseResp, userTurnOnsDtos);
        if (CollectionUtils.isEmpty(userTurnOns)) {
            chatterResponse.setTurnOnsNum(0);
            chatterResponse.setTurnOnsList(Lists.newArrayList());
            return;
        }
        final List<Integer> modelTurnOns = getTurnOns(modelResp, userTurnOnsDtos);
        if (CollectionUtils.isEmpty(modelTurnOns)) {
            chatterResponse.setTurnOnsNum(0);
            chatterResponse.setTurnOnsList(Lists.newArrayList());
            return;
        }

        if (CollectionUtils.isNotEmpty(userTurnOns) && CollectionUtils.isNotEmpty(modelTurnOns)) {
            userTurnOns.retainAll(modelTurnOns);
        }

        // user与model的turnOns不存在交集
        if (CollectionUtils.isEmpty(userTurnOns)) {
            chatterResponse.setTurnOnsNum(0);
            chatterResponse.setTurnOnsList(Lists.newArrayList());
            return;
        }

        final List<UserTurnOnsDto> turnOns = userTurnOnsDtos.stream().filter(o -> userTurnOns.contains(Integer.valueOf(String.valueOf(o.getTurnOnsCode())))).collect(Collectors.toList());
        final List<TurnOns> resultList = turnOns.stream().map(o -> TurnOns.builder().code(Integer.valueOf(String.valueOf(o.getTurnOnsCode()))).name(o.getTitle()).imageUrl(o.getImageUrl()).build()).collect(Collectors.toList());

        chatterResponse.setTurnOnsNum(resultList.size());
        chatterResponse.setTurnOnsList(resultList);
    }

    private List<Integer> getTurnOns(Response<UserBaseDto> response, List<UserTurnOnsDto> userTurnOnsDtos) {
        if (Objects.isNull(response) || !response.isSuccess() || Objects.isNull(response.getData())) {
            return Lists.newArrayList();
        }

        final String turnOnsStr = Optional.ofNullable(response.getData().getExtendInfo()).orElse("");
        if (StringUtils.isEmpty(turnOnsStr)) {
            return Lists.newArrayList();
        }

        ExtendInfoDto extendInfoDto = JSONUtil.toBean(turnOnsStr, ExtendInfoDto.class);
        return extendInfoDto.getTurnOnsList();
//        if (CollectionUtils.isEmpty(turnOnsList)) {
//            return Lists.newArrayList();
//        }
//
//        final List<UserTurnOnsDto> turnOns = userTurnOnsDtos.stream().filter(o -> turnOnsList.contains(Integer.valueOf(String.valueOf(o.getTurnOnsCode())))).collect(Collectors.toList());
//        if (CollectionUtils.isEmpty(turnOns)) {
//            return Lists.newArrayList();
//        }
//        return turnOns.stream().map(o -> TurnOns.builder().code(Integer.valueOf(String.valueOf(o.getTurnOnsCode()))).name(o.getTitle()).imageUrl(o.getImageUrl()).build()).collect(Collectors.toList());

    }

    private Response<UserBaseDto> setOnlineStatus(@RequestBody OpenChatReq req, ChatterResponse chatterResponse) {
        final Response<UserBaseDto> response = userService.getUserBaseInfo(req.getUserCodeFriend());
        if (Objects.nonNull(response) && response.isSuccess() && Objects.nonNull(response.getData())) {
            chatterResponse.setOnlineStatus(response.getData().getOnline());
            chatterResponse.setUserType(response.getData().getUserType());
            return response;
        }
        return null;
    }

    /**
     * 有效会话条数
     */
    private Integer getSumUserMsgDtos(String userCode, OpenChatReq req) {
        final List<SumUserMsgDto> sumUserMsgDtos = userMsgService.listUserMsgByFromUserCode(userCode, req.getUserCodeFriend(), ConversationType.EFFECTIVE_CONVERSATIONS.getSize());
        if (CollectionUtils.isEmpty(sumUserMsgDtos)) {
            return 0;
        }
        return sumUserMsgDtos.size();
    }

}
